package com.wtwd.campus.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wtwd.campus.chain.H5BindDeviceChain;
import com.wtwd.campus.chain.H5DeviceBindChainPattern;
import com.wtwd.campus.common.Constants;
import com.wtwd.campus.common.RespCode;
import com.wtwd.campus.common.RespEntity;
import com.wtwd.campus.entity.*;
import com.wtwd.campus.fjryE15.untils.XyyUtiils;
import com.wtwd.campus.service.*;
import com.wtwd.campus.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author ldaoliang
 * @Date create in 13:14 2021/7/16
 * @Description 设备可以被多个用户绑定  一个用户只能绑定5个设备
 */
@Api(tags = "h5管理")
@RestController
@RequestMapping("/h5")
public class H5Controller {

    private static final Logger logger = LoggerFactory.getLogger(H5Controller.class);

    @Autowired
    private H5Service h5Service;
    @Autowired
    private RedisService redisService;

    @Autowired
    private H5DeviceBindChainPattern h5DeviceBindChainPattern;

    @Resource
    private DeviceFlagService deviceFlagService;

    @Value("${h5.customerId.ryh5}")
    private Integer ryh5CustomerId;

    @Value("${h5.customerId.hbDxRyh5}")
    private Integer hbDxRyh5CustomerId;


    @Value("${h5.address}")
    private String h5Address;

    @Autowired
    private CommandSendUtils commandSendUtils;
    @Autowired
    private DeviceWhiteListService deviceWhiteListService;
    @Autowired
    private DeviceInfoService deviceInfoService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private DeviceClassPatternService deviceClassPatternService;
    @Autowired
    private WxService wxService;
    @Autowired
    private LocationService locationService;
    @Autowired
    private LogService logService;
    @Autowired
    private FenceInfoService fenceInfoService;
    @Autowired
    private DeviceSettingService deviceSettingService;
    @Autowired
    private DeviceAlarmService deviceAlarmService;
    @Resource
    private LastLocationDataService lastLocationDataService;

    /**
     * 宁夏H5 认证地址 测试域名：http://nxeducloud.linkageinfo.net
     * code 2385767
     * key 4726a851a779a0ff625f64a7c486758c
     */
    private final String nxAuthenticateUrl = "https://www.xxt.nx.chinamobile.com/educloud/api/openAPI/outer/getUserByTicket";
    private final String performCode = "2412110";
    private final String platFormKey = "557d77bc277ee58588c9993fa70905b7";

    /**
     * 湖南和教育H5 认证地址
     */
    private final String hnAuthenticateUrl = "https://hnhjyopenapi.hnsmartedu.com/typtOauth/typt/chk_oauth";

    /**
     * H5首页及认证失败地址
     */
    private final String h5IndexUrl = "https://campus.geelocks.com/h5/index.html?accessToken=";
    private final String h5ErrorUrl = "https://campus.geelocks.com/h5/index.html?/#/unbindTips";

    /**
     * 瑞翼认证地址
     */
    private final String ryAuthenticateUrl = "https://hnhjyopenapi.hnsmartedu.com/typtOauth/typt/chk_oauth";
    private final String ryToken = "901112350|7a42e16452f6c49ee255cab4509256fc.2592000000.1633488894196-e552df33438d90dbc889d2cf8593261c";

    /**
     * 长虹湖南和教育对接
     */
    private final String chAuthenticateUrl = "https://hnhjyopenapi.hnsmartedu.com/typtOauth/typt/chk_oauth";


    /**
     * 宁夏H5 token拉取用户信息及生成H5页面的token
     *
     * @param response
     * @return
     */
    @PostMapping("/authenticateAndJump")
    public void verifyToken(@RequestParam("token") String token, HttpServletResponse response) {
        logger.info("verifyToken: token = {}", token);
        //   1.构建好7个请求参数  2.发送请求 3.根据请求结果做出对应处理
        String timeStamp = String.valueOf(System.currentTimeMillis());
        String msgSeq = UUID.randomUUID().toString();
        Map<String, String> map = new HashMap<>();
        map.put("version", "1.0");
        map.put("msgType", "CHK_OAUTH");
        map.put("msgSeq", msgSeq);
        // 时间戳即可
        map.put("timeStamp", timeStamp);
        map.put("performCode", performCode);
        //获取md5加密信息
        String str = performCode + timeStamp + msgSeq + "CHK_OAUTH" + platFormKey;
        String encode = SignUtil.md5(str).toUpperCase();
        map.put("skey", encode);
        map.put("token", token);
        //拼接请求地址
        String url = nxAuthenticateUrl.concat("?");
        for (Map.Entry<String, String> m : map.entrySet()) {
            url = url.concat(m.getKey().concat("=").concat(m.getValue()).concat("&"));
        }
        // 截取最后一位 &符号
        url = url.substring(0, url.length() - 1);
        //进行请求
        logger.info("请求地址：" + url);
        JSONObject data = HttpclientUtil.postxWWWFormUrlEncode(url, null);
        //  3.1 成功则取用户id， 进行业务操作   3.2 失败、H5用户过期则跳转到错误页面
        boolean flag = false;
        String accessToken = "";
        if (data != null) {
            logger.info("响应结果" + data.toString());
            if (data.getInteger("result") == 1 && !data.containsKey("errorMessage")) {
                // 请求成功
                String userId = data.getJSONObject("data").getString("userId");
                //宁夏客户的id
                Integer cusId = 4;
                //根据客户 id获取客户使用权限到期时间
                Long expireTime = h5Service.getCusTimeByCusId(cusId);
                //判断该用户信息是否已经保存
                int h5Id = h5Service.addH5UserIfAbsent(cusId, userId);
                //生成AccessToken
                accessToken = Tools.getRamdomStr();
                //在redis中设置过期时间
                redisService.setKey(accessToken, Constants.H5_TOKEN_PREFIX + h5Id, 2, TimeUnit.HOURS);
                //进行过期时间判断
                if (System.currentTimeMillis() < expireTime) {
                    //使用权限未过期
                    flag = true;
                }
            }
        }
        try {
            if (flag) {
                response.sendRedirect(h5IndexUrl + accessToken);
                logger.info("返回页面url={}", h5IndexUrl + accessToken);
            } else {
                response.sendRedirect(h5ErrorUrl);
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("跳转失败");
        }
    }

    /**
     * 长虹 token拉取用户信息及生成H5页面的token
     *
     * @param token
     * @param response
     */
    @GetMapping("/chAuthenticationAndJump")
    public void chAuthenticationAndJump(@RequestParam("token") String token, HttpServletResponse response) {
        logger.info("/chAuthenticationAndJump: token = {}", token);
        Map<String, String> params = new HashMap<>();
        HashMap<String, String> paraData = new HashMap<>();
        params.put("accesstoken",token);
        paraData.put("data",JSONObject.toJSONString(params));
        logger.info("request: reqUrl = {}", chAuthenticateUrl);
        String s = HttpclientUtil.httpPostWithForm(chAuthenticateUrl, paraData);
        logger.info("response: param", s);
        List<Map> data = null;
        try {
            data = JSONArray.parseArray(s, Map.class);
        } catch (Exception e) {
            try {
                response.sendRedirect(h5ErrorUrl);
            } catch (IOException e1) {
                e.printStackTrace();
                logger.info("跳转失败");
            }
        }
        //  3.1 成功则取用户id， 进行业务操作   3.2 失败、H5用户过期则跳转到错误页面
        boolean flag = false;
        String accessToken = "";
        if (data != null) {
            logger.info("响应结果" + data.toString());
            if (data.size() != 0) {
                // 请求成功
                //长虹的客户id
                Integer cusId = 8;
                //根据客户 id获取客户使用权限到期时间
                Long expireTime = h5Service.getCusTimeByCusId(cusId);
                //进行过期时间判断
                if (System.currentTimeMillis() < expireTime) {
                    //使用权限未过期
                    flag = true;
                    Map map = data.get(0);
                    String userId = String.valueOf(map.get("ID"));
                    //判断该用户信息是否已经保存
                    int h5Id = h5Service.addH5UserIfAbsent(cusId, userId);
                    //生成AccessToken
                    accessToken = Tools.getRamdomStr();
                    //在redis中设置过期时间
                    redisService.setKey(accessToken, Constants.H5_TOKEN_PREFIX + h5Id, 2, TimeUnit.HOURS);
                }
            }
        }
        try {
            if (flag) {
                response.sendRedirect(h5IndexUrl + accessToken);
            } else {
                response.sendRedirect(h5ErrorUrl);
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("跳转失败");
        }
    }

    /**
     * 瑞翼E15 token拉取用户信息及生成H5页面token
     */
    @GetMapping("/reE15AuthenticationAndJump")
    public void reE15AuthenticationAndJump(@RequestParam String token, HttpServletResponse response) {
        logger.info("/reE15AuthenticationAndJump: token = {}", token);
        RyE15UserInfoData ryE15UserInfoData = XyyUtiils.getRyE15UserInfo(token);
        if (ryE15UserInfoData == null || ryE15UserInfoData.getRyE15ParentInfo() == null
                || ryE15UserInfoData.getRyE15StudentInfo() == null || StringUtils.isBlank(ryE15UserInfoData.getRyE15StudentInfo().getImei())) {
            try {
                response.sendRedirect(h5ErrorUrl);
                return;
            } catch (IOException e) {
                logger.info("跳转失败");
                e.printStackTrace();
            }
        }
        //根据客户 id获取客户使用权限到期时间
        Long expireTime = h5Service.getCusTimeByCusId(ryh5CustomerId);
        //进行过期时间判断
        if (System.currentTimeMillis() > expireTime) {
            try {
                response.sendRedirect(h5ErrorUrl);
                return;
            } catch (IOException e) {
                logger.info("跳转失败");
                e.printStackTrace();
            }
        }
        DeviceInfo device = deviceInfoService.getDeviceByImei(ryE15UserInfoData.getRyE15StudentInfo().getImei());
        if (device == null || Constants.H5_DEVICE != device.getDeviceType() || device.getCustomerId() != ryh5CustomerId) {
            try {
                response.sendRedirect(h5ErrorUrl);
                return;
            } catch (IOException e) {
                logger.info("跳转失败");
                e.printStackTrace();
            }
        }
        String userId = ryE15UserInfoData.getRyE15ParentInfo().getUserId();
        //判断该用户信息是否已经保存
        int h5Id = h5Service.addH5UserIfAbsent(ryh5CustomerId, userId);
        //同步设备用户信息
        h5Service.synchronizationUserDevice(h5Id, device.getDeviceId(), ryE15UserInfoData.getRyE15StudentInfo().getUserName());
        //生成AccessToken
        String accessToken = Tools.getRamdomStr();
        //在redis中设置过期时间
        redisService.setKey(accessToken, Constants.H5_TOKEN_PREFIX + h5Id, 2, TimeUnit.HOURS);
        try {
            response.sendRedirect(h5IndexUrl + accessToken);
            return;
        } catch (IOException e) {
            logger.info("跳转失败");
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        ArrayList<SysCustomer> sysCustomers = new ArrayList<>();
        SysCustomer sysCustomer = new SysCustomer();
        sysCustomer.setAppKey("dasdasd");
        sysCustomers.add(sysCustomer);
        System.out.println(JSONObject.toJSONString(sysCustomers));
    }

    /**
     * 瑞翼H5 token拉取用户信息及生成H5页面的token
     *
     * @param response
     * @return
     */
//    @PostMapping("/ryAuthenticationAndJump")
    @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST}, value = "ryAuthenticationAndJump")
    public void ryAuthenticationAndJump(@RequestParam("token") String token, HttpServletResponse response) {
        logger.info("/ryAuthenticationAndJump: token = {}", token);
        Map<String, String> params = new HashMap<>();
        HashMap<String, String> paraData = new HashMap<>();
        params.put("accesstoken",token);
        paraData.put("data",JSONObject.toJSONString(params));
        logger.info("request: reqUrl = {}", ryAuthenticateUrl);
        String s = HttpclientUtil.httpPostWithForm(ryAuthenticateUrl, paraData);
        logger.info("response: param", s);
        List<Map> data = null;
        try {
            data = JSONArray.parseArray(s, Map.class);
        } catch (Exception e) {
            try {
                response.sendRedirect(h5ErrorUrl);
            } catch (IOException e1) {
                e.printStackTrace();
                logger.info("跳转失败");
            }
        }
        //  3.1 成功则取用户id， 进行业务操作   3.2 失败、H5用户过期则跳转到错误页面
        boolean flag = false;
        String accessToken = "";
        if (data != null) {
            logger.info("响应结果" + data.toString());
            if (data.size() != 0) {
                // 请求成功
                //瑞翼客户的id
                Integer cusId = 5;
                //根据客户 id获取客户使用权限到期时间
                Long expireTime = h5Service.getCusTimeByCusId(cusId);
                //进行过期时间判断
                if (System.currentTimeMillis() < expireTime) {
                    //使用权限未过期
                    flag = true;
                    Map map = data.get(0);
                    String userId = String.valueOf(map.get("ID"));
                    //判断该用户信息是否已经保存
                    int h5Id = h5Service.addH5UserIfAbsent(cusId, userId);
                    //生成AccessToken
                    accessToken = Tools.getRamdomStr();
                    //在redis中设置过期时间
                    redisService.setKey(accessToken, Constants.H5_TOKEN_PREFIX + h5Id, 2, TimeUnit.HOURS);
                }
            }
        }
        try {
            if (flag) {
                response.sendRedirect(h5IndexUrl + accessToken);
            } else {
                response.sendRedirect(h5ErrorUrl);
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("跳转失败");
        }
    }

    /**
     * 湖南和教育H5 token拉取用户信息及生成H5页面的token
     *
     * @param response
     * @return
     */
    @GetMapping("/hnhjyAuthenticateAndJump")
    public void hnhjyAuthenticateAndJump(@RequestParam("accesstoken") String token, HttpServletResponse response) {
        logger.info("/hnhjyAuthenticateAndJump: token = {}", token);
        Map<String, String> params = new HashMap<>();
        HashMap<String, String> paraData = new HashMap<>();
        params.put("accesstoken",token);
        paraData.put("data",JSONObject.toJSONString(params));
        logger.info("request: reqUrl = {}", hnAuthenticateUrl);
        String s = HttpclientUtil.httpPostWithForm(hnAuthenticateUrl, paraData);
        logger.info("response: param", s);
        List<Map> data = null;
        try {
            data = JSONArray.parseArray(s, Map.class);
        } catch (Exception e) {
            try {
                response.sendRedirect(h5ErrorUrl);
            } catch (IOException e1) {
                e.printStackTrace();
                logger.info("跳转失败");
            }
        }
        //  3.1 成功则取用户id， 进行业务操作   3.2 失败、H5用户过期则跳转到错误页面
        boolean flag = false;
        String accessToken = "";
        if (data != null) {
            logger.info("响应结果" + data.toString());
            if (data.size() != 0) {
                // 请求成功
                //湖南客户的id
                Integer cusId = 6;
                //根据客户 id获取客户使用权限到期时间
                Long expireTime = h5Service.getCusTimeByCusId(cusId);
                //进行过期时间判断
                if (System.currentTimeMillis() < expireTime) {
                    //使用权限未过期
                    flag = true;
                    Map map = data.get(0);
                    String userId = String.valueOf(map.get("ID"));
                    //判断该用户信息是否已经保存
                    int h5Id = h5Service.addH5UserIfAbsent(cusId, userId);
                    //生成AccessToken
                    accessToken = Tools.getRamdomStr();
                    //在redis中设置过期时间
                    redisService.setKey(accessToken, Constants.H5_TOKEN_PREFIX + h5Id, 2, TimeUnit.HOURS);
                }
            }
        }
        try {
            if (flag) {
                response.sendRedirect(h5IndexUrl + accessToken);
            } else {
                response.sendRedirect(h5ErrorUrl);
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("跳转失败");
        }
    }


    /**
     * 外部app调用该接口获取登录页地址及token
     *
     * @param request
     * @return
     */
    @GetMapping("/jumpIndex")
    public RespEntity jumpIndex(HttpServletRequest request) {
        String appKey = request.getParameter("appKey");
        String userId = request.getParameter("userId");
        String imei = request.getParameter("imei");
        String uname = request.getParameter("uname");
        logger.info("外部app请求进入H5页面：appKey = [{}],userId = [{}],imei=[{}],uname=[{}]", appKey, userId, imei, uname);
        H5Customer h5Customer = h5Service.getH5CustomerByAppKey(appKey);
        if (h5Customer == null) {
            return new RespEntity(RespCode.FAILED);
        }
        //进行过期时间判断
        if (System.currentTimeMillis() > h5Customer.getExpireTime()) {
            return new RespEntity(RespCode.H5_USE_TIME_EXPIRE);
        }
        int h5Id = h5Service.addH5UserIfAbsent(h5Customer.getId(), userId);
        if (hbDxRyh5CustomerId.equals(h5Customer.getId())) {//湖北电信睿翼e15在请求时同步设备用户绑定关系
            if (StringUtils.isBlank(imei) || StringUtils.isBlank(uname)) {
                return new RespEntity(RespCode.PARAMS_ERROR);
            }
            DeviceInfo device = deviceInfoService.getDeviceByImei(imei);
            if (device == null||!hbDxRyh5CustomerId.equals(device.getCustomerId())||Constants.H5_DEVICE!=device.getDeviceType()) {
                return new RespEntity(RespCode.DEVICE_NOT_FOUND);
            }
            h5Service.synchronizationUserDevice(h5Id, device.getDeviceId(), uname);
        }
        String token = Tools.getRamdomStr();
        redisService.setKey(token, Constants.H5_TOKEN_PREFIX + h5Id, 2, TimeUnit.HOURS);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("index.url", h5Address);
        jsonObject.put("accessToken", token);
        return new RespEntity(RespCode.SUCCESS, jsonObject);
    }

    /**
     * 决策跳转
     *
     * @param request
     * @return
     */
    @GetMapping("/decisionJump")
    public RespEntity decisionJump(HttpServletRequest request) {
        String token = request.getHeader("Access-Token");
        logger.info("/decisionJump: token = {}", token);
        String value = redisService.getValue(token);
        if (StringUtils.isBlank(value) || !value.contains(Constants.H5_TOKEN_PREFIX)) {
            logger.info("未登录,跳转到未登录页面");
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        // 校验是否绑定设备
        Integer h5UserId = Integer.parseInt(value.split("_")[1]);
        List<Integer> deviceList = h5Service.deviceIdList(h5UserId);
        if (deviceList == null || deviceList.size() == 0) {
            logger.info("未绑定设备，跳转到绑定页面");
            return new RespEntity(RespCode.USER_NOT_BIND_DEVICE);
        }
        logger.info("跳转成功");
        return new RespEntity(RespCode.SUCCESS);
    }

    /**
     * 用户设备列表
     *
     * @param request
     * @return
     */
    @GetMapping("/deviceList")
    public RespEntity deviceList(HttpServletRequest request) {
        String token = request.getHeader("Access-Token");
        String value = redisService.getValue(token);
        if (StringUtils.isBlank(value) || !value.contains(Constants.H5_TOKEN_PREFIX)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer h5UserId = Integer.parseInt(value.split("_")[1]);
        logger.info("查看用户绑定列表。h5UserId = {}", h5UserId);
        List<Map<String, Object>> deviceList = h5Service.deviceList(h5UserId);
        return new RespEntity(RespCode.SUCCESS, deviceList);
    }

    /**
     * 修改设备imei
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/modifySimCardMess")
    public RespEntity modifySimCardMess(@RequestBody JSONObject data, HttpServletRequest request) {
        Integer deviceId = data.getInteger("deviceId");
        String phone = data.getString("phone");
        logger.info("/modifySimCardMess:deviceId={},phone={}" + deviceId + phone);
        int i = h5Service.modifyPhoneByDeviceId(deviceId, phone);
        return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
    }

    /**
     * 绑定设备
     *
     * @param jsonObject
     * @param request
     * @return
     */
    @PostMapping("/bindingDevice")
    public RespEntity bindingDevice(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
        String token = request.getHeader("Access-Token");
        String value = redisService.getValue(token);
        if (StringUtils.isBlank(value) || !value.contains(Constants.H5_TOKEN_PREFIX)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer h5UserId = Integer.parseInt(value.split("_")[1]);
        String studentName = jsonObject.getString("studentName");
        String imei = jsonObject.getString("imei");
        logger.info("用户绑定设备:h5UserId = {}, imei = {}, studentName = {}", h5UserId, imei, studentName);
        if (Tools.stringIsBlank(imei, studentName)) {
            return new RespEntity(RespCode.PARAMETERIS_MiSSING);
        }
        H5BindDeviceChain h5DeviceBindChain = h5DeviceBindChainPattern.getH5DeviceBindChain();
        return h5DeviceBindChain.submitH5BindDevice(H5BindDeviceChain.bindDevice, h5UserId, imei, studentName);
    }

    /**
     * 解绑
     *
     * @param deviceId
     * @param request
     * @return
     */
    @DeleteMapping("/unbindDevice/{deviceId}")
    public RespEntity unbindDevice(@PathVariable("deviceId") Integer deviceId, HttpServletRequest request) {
        String token = request.getHeader("Access-Token");
        String value = redisService.getValue(token);
        if (StringUtils.isBlank(value) || !value.contains(Constants.H5_TOKEN_PREFIX)) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer h5UserId = Integer.parseInt(value.split("_")[1]);
        H5User h5User = h5Service.getH5UserById(h5UserId);
        if (h5User==null){
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        if (h5User.getH5CustomerId().equals(hbDxRyh5CustomerId)||h5User.getH5CustomerId().equals(ryh5CustomerId)){
            return new RespEntity(RespCode.NONSUPPORT_UNBIND);
        }
        logger.info("解绑设备: deviceId = {},h5UserId = {}", deviceId, h5UserId);
        return h5Service.unbindDevice(deviceId, h5UserId);
    }

    /**
     * 获取亲情号码的列表
     *
     * @param deviceId
     * @return
     */
    @GetMapping("/getAffectionNumberList")
    public RespEntity getAffectionNumberList(@RequestParam("deviceId") Integer deviceId) {
        logger.info("getAffectionNumberList : deviceId = " + deviceId.toString());
        List<DeviceWhiteList> whiteList = deviceWhiteListService.getAffectionNumberByDeviceId(deviceId);
        List<DeviceWhiteList> result = new ArrayList<>();
        if (whiteList != null && whiteList.size() > 0) {
            for (DeviceWhiteList white : whiteList) {
                if (white.getSequence() >= 4 && white.getSequence() <= 6) {
                    result.add(white);
                }
            }
        }
        return new RespEntity(RespCode.SUCCESS, result);
    }


    /**
     * 编辑亲情号
     *
     * @return
     */
    @PostMapping("/modifyAffectionNumber")
    public RespEntity modifyAffectionNumber(@RequestBody DeviceWhiteList white, HttpServletRequest request) {
        logger.info("modifyAffectionNumber : white = " + white.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找亲情号列表
        DeviceWhiteList oldWhiteMess = deviceWhiteListService.getDeviceWhiteListById(white.getId());
        //根据设备id查找设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(oldWhiteMess.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        //判断该亲情号码是否已经存在
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByDeviceId(deviceInfo.getDeviceId());
        for (DeviceWhiteList w : list) {
            if ((w.getSequence() >= 4 && w.getSequence() <= 6) && w.getWhitePhone().equals(white.getWhitePhone()) && oldWhiteMess.getSequence() != w.getSequence()) {
                return new RespEntity(RespCode.WHITE_NUMBER_REPEAT);
            }
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceInfo.getDeviceId());
        if (b) {
            //修改亲情号信息
            white.setStatus(Constants.WHITE_PATTERN_STAY_UPDATE);
            Integer i = deviceWhiteListService.modifyAffectionNumber(white);
            if (i > 0) {
                //进行指令下发进行修改
                DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
                deviceWhiteCall.setImei(deviceInfo.getImei());
                deviceWhiteCall.setCommandNumber(getCurTime());
                deviceWhiteCall.setSequence(oldWhiteMess.getSequence());
                deviceWhiteCall.setPhone(white.getWhitePhone());
                deviceWhiteCall.setName(white.getWhiteName());
                deviceWhiteCall.setDeviceId(deviceInfo.getDeviceId());
                deviceWhiteCall.setStatus(Constants.WHITE_PATTERN_STAY_UPDATE);
                deviceWhiteCall.setIsAffection(1);
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.updateDeviceWhiteCall(deviceWhiteCall, isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 添加亲情号
     *
     * @return
     */
    @PostMapping("/addAffectionNumber")
    public RespEntity addAffectionNumber(@RequestBody JSONObject data, HttpServletRequest request) {
        logger.info("addAffectionNumber : data = {}  " + data.toString());
        Integer deviceId = data.getInteger("deviceId");
        String name = data.getString("name");
        String number = data.getString("number");
        Integer sequence = data.getInteger("sequence");
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("H5用户ID ： " + userId);
        //根据设备id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该亲情号码是否已经存在
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByDeviceId(deviceId);
        for (DeviceWhiteList white : list) {
            if (white.getWhitePhone().equals(number) && (white.getSequence() >= 4 && white.getSequence() <= 6)) {
                return new RespEntity(RespCode.WHITE_NUMBER_REPEAT);
            }
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceId);
        if (b) {
            DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
            deviceWhiteCall.setImei(deviceInfo.getImei());
            deviceWhiteCall.setCommandNumber(getCurTime());
            deviceWhiteCall.setSequence(sequence);
            deviceWhiteCall.setPhone(number);
            deviceWhiteCall.setName(name);
            deviceWhiteCall.setDeviceId(deviceInfo.getDeviceId());
            deviceWhiteCall.setStatus(Constants.WHITE_PATTERN_STAY_ADD);
            deviceWhiteCall.setIsAffection(1);
            //进行亲情号的添加
            Integer i = deviceWhiteListService.addDeviceWhiteList(deviceWhiteCall);
            if (i > 0) {
                //进行指令下发添加亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.addWhiteCall(deviceWhiteCall, isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 删除亲情号
     *
     * @return
     */
    @DeleteMapping("/delAffectionNumber/{id}")
    public RespEntity delAffectionNumber(@PathVariable("id") Integer id,
                                         HttpServletRequest request) {
        logger.info("/delAffectionNumber : id = {}  " + id.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找亲情号列表
        DeviceWhiteList oldWhiteMess = deviceWhiteListService.getDeviceWhiteListById(id);
        if (oldWhiteMess == null) {
            return new RespEntity(RespCode.NO_DATA);
        }
        //根据设备id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(oldWhiteMess.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceInfo.getDeviceId());
        if (b) {
            //将亲情号的状态设置为待删除
            DeviceWhiteList white = new DeviceWhiteList();
            white.setStatus(Constants.WHITE_PATTERN_STAY_DELETE);
            white.setId(id);
            Integer i = deviceWhiteListService.modifyAffectionNumber(white);
            if (i > 0) {
                //进行指令下发删除亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.delWhiteCall(deviceInfo.getImei(), getCurTime(), oldWhiteMess.getSequence(), isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 获取通讯录列表
     *
     * @param deviceId
     * @return
     */
    @GetMapping("/getWhiteList")
    public RespEntity getWhiteList(@RequestParam("deviceId") Integer deviceId) {
        logger.info("getWhiteList : deviceId = " + deviceId);
        List<DeviceWhiteList> whiteList = deviceWhiteListService.getAffectionNumberByDeviceId(deviceId);
        List<DeviceWhiteList> result = new ArrayList<>();
        if (whiteList != null && whiteList.size() > 0) {
            for (DeviceWhiteList white : whiteList) {
                if (white.getSequence() > 6) {
                    result.add(white);
                }
            }
        }
        return new RespEntity(RespCode.SUCCESS, result);
    }


    /**
     * 编辑通讯录联系人
     *
     * @return
     */
    @PutMapping("/modifyLinkMan")
    public RespEntity modifyLinkMan(@RequestBody DeviceWhiteList white, HttpServletRequest request) {
        logger.info("modifyLinkMan : white = " + white.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找亲情号列表
        DeviceWhiteList oldWhiteMess = deviceWhiteListService.getDeviceWhiteListById(white.getId());
        //根据设备id查找设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(oldWhiteMess.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        //判断该亲情号码是否已经存在
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByDeviceId(deviceInfo.getDeviceId());
        for (DeviceWhiteList w : list) {
            if ((w.getSequence() >= 7) && w.getWhitePhone().equals(white.getWhitePhone()) && oldWhiteMess.getSequence() != w.getSequence()) {
                return new RespEntity(RespCode.WHITE_NUMBER_REPEAT);
            }
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceInfo.getDeviceId());
        if (b) {
            //修改亲情号信息
            white.setStatus(Constants.WHITE_PATTERN_STAY_UPDATE);
            Integer i = deviceWhiteListService.modifyAffectionNumber(white);
            if (i > 0) {
                //进行指令下发进行修改
                DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
                deviceWhiteCall.setImei(deviceInfo.getImei());
                deviceWhiteCall.setCommandNumber(getCurTime());
                deviceWhiteCall.setSequence(oldWhiteMess.getSequence());
                deviceWhiteCall.setPhone(white.getWhitePhone());
                deviceWhiteCall.setName(white.getWhiteName());
                deviceWhiteCall.setDeviceId(deviceInfo.getDeviceId());
                deviceWhiteCall.setStatus(Constants.WHITE_PATTERN_STAY_UPDATE);
                deviceWhiteCall.setIsAffection(1);
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.updateDeviceWhiteCall(deviceWhiteCall, isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 添加通讯录联系人
     *
     * @return
     */
    @PostMapping("/addLinkMan")
    public RespEntity addLinkMan(@RequestBody JSONObject data, HttpServletRequest request) {
        logger.info("addLinkMan : data = {} " + data.toString());
        Integer deviceId = (Integer) data.get("deviceId");
        String name = (String) data.get("name");
        String number = (String) data.get("number");
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该亲情号码是否已经存在
        List<DeviceWhiteList> list = deviceWhiteListService.getAffectionNumberByDeviceId(deviceId);
        for (DeviceWhiteList white : list) {
            if ((white.getSequence() >= 7) && white.getWhitePhone().equals(number)) {
                return new RespEntity(RespCode.WHITE_NUMBER_REPEAT);
            }
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceId);
        if (b) {
            //选取一个可用亲情号的序列号
            Integer sequence = getSequenceInLink(list);
            if (sequence == 0) {
                return new RespEntity(RespCode.UPLOAD_PEOPLE);
            }
            DeviceWhiteCall deviceWhiteCall = new DeviceWhiteCall();
            deviceWhiteCall.setImei(deviceInfo.getImei());
            deviceWhiteCall.setCommandNumber(getCurTime());
            deviceWhiteCall.setSequence(sequence);
            deviceWhiteCall.setPhone(number);
            deviceWhiteCall.setName(name);
            deviceWhiteCall.setDeviceId(deviceInfo.getDeviceId());
            deviceWhiteCall.setStatus(Constants.WHITE_PATTERN_STAY_ADD);
            deviceWhiteCall.setIsAffection(0);
            //进行亲情号的添加
            Integer i = deviceWhiteListService.addDeviceWhiteList(deviceWhiteCall);
            if (i > 0) {
                //进行指令下发添加亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.addWhiteCall(deviceWhiteCall, isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 删除联系人
     *
     * @return
     */
    @DeleteMapping("/delLinkMan/{id}")
    public RespEntity delLinkMan(@PathVariable("id") Integer id,
                                 HttpServletRequest request) {
        logger.info("delLinkMan : id = {}  " + id.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找亲情号列表
        DeviceWhiteList oldWhiteMess = deviceWhiteListService.getDeviceWhiteListById(id);
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(oldWhiteMess.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceInfo.getDeviceId());
        if (b) {
            //将亲情号的状态设置为待删除
            DeviceWhiteList white = new DeviceWhiteList();
            white.setStatus(Constants.WHITE_PATTERN_STAY_DELETE);
            white.setId(id);
            Integer i = deviceWhiteListService.modifyAffectionNumber(white);
            if (i > 0) {
                //进行指令下发删除亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.delWhiteCall(deviceInfo.getImei(), getCurTime(), oldWhiteMess.getSequence(), isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 查看课堂模式列表
     *
     * @param deviceId
     * @return
     */
    @GetMapping("/getClassModeList")
    public RespEntity getClassModeList(@RequestParam("deviceId") Integer deviceId) {
        logger.info("getClassModeList : deviceId = {}", deviceId);
        List<DeviceClassPattern> deviceClassPatternList = deviceClassPatternService.getDeviceClassesPatternByDeviceId(deviceId);
        if (deviceClassPatternList != null && deviceClassPatternList.size() != 0) {
            for (DeviceClassPattern deviceClassPattern : deviceClassPatternList) {
                //处理课堂模式开关数据
                String repeatTime = deviceClassPattern.getRepeatTime();
                char[] chars = repeatTime.toCharArray();
                String s = ArrayUtils.toString(chars, ",");
                int length = s.length();
                String result = s.substring(1, length - 1);
                deviceClassPattern.setRepeatTime(result);
            }
        }
        return new RespEntity(RespCode.SUCCESS, deviceClassPatternList);
    }

    /**
     * 添加课堂模式
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/addClassMode")
    public RespEntity addClassMode(@RequestBody ClassModeVo data, HttpServletRequest request) {
        logger.info("addClassMode : data = {}", data.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(data.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        Integer sequence = getClassSequence(deviceInfo.getDeviceId());
        if (sequence == 0) {
            return new RespEntity(RespCode.CLASS_PATTERN_UPLOAD);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceInfo.getDeviceId());
        if (b) {
            //处理重复的开关
            String repeatTime = data.getList();
            String replace = repeatTime.replace(",", "");
            DeviceClassMode mode = new DeviceClassMode();
            mode.setEndTime(data.getEnd());
            mode.setImei(deviceInfo.getImei());
            mode.setSequence(sequence);
            mode.setCommandNumber(getCurTime());
            mode.setDeviceId(deviceInfo.getDeviceId());
            mode.setRepeatTime(replace);
            mode.setStartTime(data.getStart());
            mode.setOnOff(1);//默认开
            mode.setStatus(Constants.CLASSES_PATTERN_STAY_ADD);
            //在数据库添加一笔课堂模式数据
            int i = deviceClassPatternService.addDeviceClassPattern(mode);
            if (i > 0) {
                //指令下发进行添加课堂模式
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.addClassMode(mode, isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 修改课堂模式
     *
     * @param data
     * @param request
     * @return
     */
    @PutMapping("/modifyClassMode")
    public RespEntity modifyClassMode(@RequestBody ClassModeVo data, HttpServletRequest request) {
        logger.info("modifyClassMode : data = {}", data.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(data.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
       /* //根据课堂模式id查找课堂模式记录
        DeviceClassPattern classPattern = deviceClassPatternService.getClassModeById(data.getId());*/
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceInfo.getDeviceId());
        if (b) {
            //处理重复的开关
            String repeatTime = data.getList();
            String replace = repeatTime.replace(",", "");
            String commandNumber = getCurTime();
            DeviceClassMode mode = new DeviceClassMode();
            mode.setEndTime(data.getEnd());
            mode.setImei(deviceInfo.getImei());
            mode.setSequence(data.getSequence());
            mode.setCommandNumber(commandNumber);
            mode.setDeviceId(deviceInfo.getDeviceId());
            mode.setRepeatTime(replace);
            mode.setStartTime(data.getStart());
            mode.setOnOff(1);//默认开
            mode.setStatus(Constants.CLASSES_PATTERN_STAY_UPDATE);
            //修改课堂模式的状态为待修改
            int i = deviceClassPatternService.updateClassPatternStatus2(data.getId(), Constants.CLASSES_PATTERN_STAY_UPDATE, commandNumber);
            if (i > 0) {
                //指令下发进行添加课堂模式
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.updateClassMode(mode, isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 删除课堂模式
     *
     * @param id
     * @param request
     * @return
     */
    @DeleteMapping("/delClassMode/{id}")
    public RespEntity delClassMode(@PathVariable("id") Integer id,
                                   HttpServletRequest request) {
        logger.info("delClassMode : id = {}  " + id.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据课堂模式id查找课堂模式记录
        DeviceClassPattern classPattern = deviceClassPatternService.getClassModeById(id);
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(classPattern.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceInfo.getDeviceId());
        if (b) {
            //将课堂模式的状态设置为待删除
            String commandNumber = getCurTime();
            Integer i = deviceClassPatternService.updateClassPatternStatus2(id, Constants.CLASSES_PATTERN_STAY_DELETE, commandNumber);
            if (i > 0) {
                //进行指令下发删除亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                boolean b1 = commandSendUtils.delClassMode(deviceInfo.getImei(), commandNumber, classPattern.getSequence(), isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 获取课堂模式
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/getClassMode")
    public RespEntity getClassMode(@RequestParam("id") Integer id,
                                   HttpServletRequest request) {
        logger.info("getClassMode : id = {}  " + id.toString());
        //根据课堂模式id查找课堂模式记录
        DeviceClassPattern classPattern = deviceClassPatternService.getClassModeById(id);
        if (classPattern != null) {
            //处理课堂模式开关数据
            String repeatTime = classPattern.getRepeatTime();
            char[] chars = repeatTime.toCharArray();
            String s = ArrayUtils.toString(chars, ",");
            int length = s.length();
            String result = s.substring(1, length - 1);
            classPattern.setRepeatTime(result);
            return new RespEntity(RespCode.SUCCESS, classPattern);
        }
        return new RespEntity(RespCode.FAILED);
    }

    /**
     * 设置设备监听号码
     *
     * @param data
     * @param request
     * @return
     */
    @PutMapping("/setMonitorNumber")
    public RespEntity setMonitorNumber(@RequestBody JSONObject data,
                                       HttpServletRequest request) {
        logger.info("setMonitorNumber : data = {}  " + data.toString());
        Integer deviceId = (Integer) data.get("deviceId");
        String number = (String) data.get("number");
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        /*Integer userId =1;*/
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断设备是否在线
        boolean b1 = deviceOnline(deviceInfo.getImei());
        if (!b1) {
            return new RespEntity(RespCode.DEVICE_OFF_LINE);
        }
        Boolean authMonitorNumber = deviceInfoService.authMonitorNumber(deviceInfo.getDeviceId(), number);
        if (!authMonitorNumber) {
            return new RespEntity(RespCode.MONITOR_PHONE_ERROR);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceId);
        if (b) {
            //查找该设备的设置信息
            DeviceSetting setting = deviceInfoService.getDeviceSettingByDeviceId(deviceInfo.getDeviceId());
            if (setting != null) {
                String commandNumber = getCurTime();
                setting.setMonitorNum(number);
                //修改设备设置信息
                int i = deviceInfoService.modifyDeviceInfoSetting(setting);
                if (i > 0) {
                    //进行指令下发
                    boolean b2 = commandSendUtils.setMonitorPhone(deviceInfo.getImei(), commandNumber, number, Constants.H5_COMMAND_USER_ID);
                    if (b2) {
                        return new RespEntity(RespCode.SUCCESS);
                    }
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 查询学生定位
     *
     * @param deviceId
     * @param request
     * @return
     */
    @ApiOperation(value = "查询学生定位", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceId", value = "设备id", required = true, dataTypeClass = Integer.class)
    })
    @GetMapping("/queryStudentLocation")
    public RespEntity queryStudentLocation(@RequestParam("deviceId") Integer deviceId,
                                           HttpServletRequest request) {
        logger.info("queryStudentLocation : deviceId = {},id = {}  " + deviceId.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据用户id查询绑定设备
        List<Map<String, Object>> deviceList = h5Service.deviceList(userId);
        if (deviceList == null || deviceList.size() == 0) {
            return new RespEntity(RespCode.USER_NOT_BIND_DEVICE);
        }
        List<Integer> queryList = new ArrayList<>();
        //判断查询单个学生还是所有学生
        if (deviceId == 0) {
            //查询所有
            for (Map<String, Object> map : deviceList) {
                queryList.add((Integer) map.get("device_id"));
            }
        } else {
            queryList.add(deviceId);
        }
        List<Map<String, Object>> locationList = lastLocationDataService.queryH5LastLocationDataByDeviceIds(queryList,userId);
        if (locationList!=null&&locationList.size()>0){
            List<String> imeis = locationList.stream().map(e -> (String) e.get("imei")).collect(Collectors.toList());
            Map<String, Boolean> stringBooleanMap = deviceFlagService.bathGetDeviceOnline(imeis);
            for (Map<String, Object> map : locationList) {
                map.put("isOnline", stringBooleanMap.get((String)map.get("imei")) ? "在线" : "离线");
            }
        }
        return new RespEntity(RespCode.SUCCESS, locationList);
    }


    /**
     * 获取设备的轨迹
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/getAttackByDeviceId")
    public RespEntity getAttackByDeviceId(@RequestBody JSONObject data,
                                          HttpServletRequest request) {
        logger.info("getAttackByDeviceId : data = {}  " + data.toString());
        Integer deviceId = (Integer) data.get("deviceId");
        Long time = (Long) data.get("time");
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据设备id和时间获取设备当天的轨迹
        List<Map<String, Object>> trackList = locationService.getDeviceTrackByDeviceId(deviceId, time);
        //数据去重
        ArrayList<Map<String, Object>> result = trackList.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<Map<String, Object>>(
                        Comparator.comparing(o -> (Integer) o.get("id")))), ArrayList::new));
        //对轨迹数据进行处理筛选
        List<Map<String, Object>> list = dealLocation(result);
        if (trackList != null && trackList.size() != 0) {
            return new RespEntity(RespCode.SUCCESS, list);
        }
        return new RespEntity(RespCode.SUCCESS, list);
    }

    /**
     * 根据设备id获取设备sos列表
     *
     * @param deviceId
     * @param request
     * @return
     */
    @GetMapping("/getSOSList")
    public RespEntity getSOSList(@RequestParam("deviceId") Integer deviceId,
                                 HttpServletRequest request) {
        logger.info("getSOSList : deviceId = {},id = {}  " + deviceId.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //获取sos列表
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceId);
        return new RespEntity(RespCode.SUCCESS, sosList);
    }


    /**
     * 修改SOS信息
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/modifySOSMessage")
    public RespEntity modifySOSMessage(@RequestBody SOSListVO data, HttpServletRequest request) {
        logger.info("modifySOSMessage : data = {}", data.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据设备id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(data.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceInfo.getDeviceId());
        if (b) {
            //获取该设备所有的sos号码列表,判断是否重复
            List<DeviceSOSList> list = logService.getSOSListByDeviceId(deviceInfo.getDeviceId());
            for (DeviceSOSList sos : list) {
                if (sos.getSosPhone().equals(data.getPhone()) && sos.getSequence() != data.getSequence()) {
                    return new RespEntity(RespCode.NUMBER_HAD_USED);
                }
            }
            //获取流水号
            String commandNumber = getCurTime();
            DeviceSOSList sos = new DeviceSOSList();
            sos.setDeviceId(deviceInfo.getDeviceId());
            sos.setCommandNumber(commandNumber);
            sos.setSequence(data.getSequence());
            sos.setSosName(data.getName());
            sos.setSosPhone(data.getPhone());
            sos.setStatus(Constants.DEVICE_SOS_STAY_UPDATE);
           /* //修改SOS号码的状态为待修改
            int i = logService.updateSosListStatus(data.getId(), Constants.DEVICE_SOS_STAY_UPDATE, commandNumber);*/
            //修改SOS号码的状态为待修改，同时修改数据
            Integer i = logService.updateSosListData(data, Constants.DEVICE_SOS_STAY_UPDATE, commandNumber);
            if (i > 0) {
                //指令下发进行修改SOS信息
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                List<DeviceSOSList> modifySOSList = getModifySetSOSList(sos, deviceInfo.getDeviceId());
                boolean b1 = commandSendUtils.setAllSosCall(modifySOSList, deviceInfo.getImei(), commandNumber, isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 添加SOS信息
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/addSOSList")
    public RespEntity addSOSList(@RequestBody SOSListVO data, HttpServletRequest request) {
        logger.info("addSOSList : data = {}", data.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(data.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        Integer sequence = getSosSequence(deviceInfo.getDeviceId());
        if (sequence == 0) {
            return new RespEntity(RespCode.SOS_NUMBER_UPLOAD);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceInfo.getDeviceId());
        if (b) {
            //获取该设备所有的sos号码列表,判断是否重复
            List<DeviceSOSList> list = logService.getSOSListByDeviceId(deviceInfo.getDeviceId());
            for (DeviceSOSList sos : list) {
                if (sos.getSosPhone().equals(data.getPhone())) {
                    return new RespEntity(RespCode.NUMBER_HAD_USED);
                }
            }
            String commandNumber = getCurTime();
            DeviceSOSList sos = new DeviceSOSList();
            sos.setDeviceId(deviceInfo.getDeviceId());
            sos.setCommandNumber(commandNumber);
            sos.setSequence(sequence);
            sos.setSosName(data.getName());
            sos.setSosPhone(data.getPhone());
            sos.setStatus(Constants.DEVICE_SOS_STAY_ADD);
            //在数据库添加一笔SOS号码信息
            int i = logService.insertSosNumberList(sos);
            if (i > 0) {
                //指令下发进行添加SOS号码
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                List<DeviceSOSList> sosList = getAddSetSOSList(sos, deviceInfo.getDeviceId());
                boolean b1 = commandSendUtils.setAllSosCall(sosList, deviceInfo.getImei(), commandNumber, isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 删除SOS信息
     *
     * @param id
     * @param request
     * @return
     */
    @DeleteMapping("/delSOSMess/{id}")
    public RespEntity delSOSMess(@PathVariable("id") Integer id,
                                 HttpServletRequest request) {
        logger.info("delSOSMess : id = {}  " + id.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找SOS信息
        DeviceSOSList sosMess = logService.getDeviceSOSMessById(id);
        //根据学生id查找设备
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(sosMess.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        //判断该家长是否有权限操作
        boolean b = veryAuthentication(userId, deviceInfo.getDeviceId());
        if (b) {
            //将sos号码信息的状态设置为待删除
            String commandNumber = getCurTime();
            Integer i = logService.updateSosListStatus(id, Constants.DEVICE_SOS_DELETE, commandNumber);
            if (i > 0) {
                DeviceSOSList sos = new DeviceSOSList();
                sos.setDeviceId(deviceInfo.getDeviceId());
                sos.setCommandNumber(commandNumber);
                sos.setSequence(sosMess.getSequence());
                sos.setSosName("");
                sos.setSosPhone("");
                //进行指令下发删除亲情号
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                List<DeviceSOSList> sosList = getDelSetSOSList(sos, deviceInfo.getDeviceId());
                boolean b1 = commandSendUtils.setAllSosCall(sosList, deviceInfo.getImei(), commandNumber, isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 根据id获取sos信息
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/getSOSMessById")
    public RespEntity getSOSMessById(@RequestParam("id") Integer id,
                                     HttpServletRequest request) {
        logger.info("getSOSMessById : id = {}  " + id.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        //根据id查找SOS记录
        DeviceSOSList sos = logService.getDeviceSOSMessById(id);
        return new RespEntity(sos == null ? RespCode.FAILED : RespCode.SUCCESS, sos);
    }

    /**
     * 获取通话记录
     *
     * @param deviceId
     * @param request
     * @return
     */
    @GetMapping("/getCallRecord")
    public RespEntity getCallRecord(@RequestParam("deviceId") Integer deviceId, HttpServletRequest request) {
        logger.info("getCallRecord : deviceId = {}" + deviceId.toString());
        //根据学生id获取通话记录
        List<Map<String, Object>> callList = logService.getCallRecordByDeviceId(deviceId);
        return new RespEntity(RespCode.SUCCESS, callList);
    }

    /**
     * 根据设备id查找电子围栏
     *
     * @param deviceId
     * @param request
     * @return
     */
    @GetMapping("/getFenceInfoByDeviceId")
    public RespEntity getFenceInfoByDeviceId(@RequestParam("deviceId") Integer deviceId, HttpServletRequest request) {
        logger.info("getFenceInfoByDeviceId : deviceId = {}" + deviceId.toString());
        //根据设备id获取电子围栏
        List<H5Fence> fenceList = fenceInfoService.getH5FenceByDeviceId(deviceId);
        //将电子围栏的经纬度转换成高德后再给前端
       /* for(H5Fence e:fenceList){
            double[] doubles = GPSUtils.gps84_To_Gcj02(Double.parseDouble(e.getLatitude()), Double.parseDouble(e.getLongitude()));
            double[] doubles2 = GPSUtils.gps84_To_Gcj02(doubles[0], doubles[1]);
            e.setLatitude(String.valueOf(doubles2[0]));
            e.setLongitude(String.valueOf(doubles2[1]));
        }*/
        return new RespEntity(RespCode.SUCCESS, fenceList);
    }

    /**
     * 根据id删除围栏
     *
     * @param id
     * @param request
     * @return
     */
    @DeleteMapping("/delFenceById/{id}")
    public RespEntity delFenceById(@PathVariable("id") Integer id, HttpServletRequest request) {
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/delFenceById : id = {}" + id.toString());
        //判断是否有权限操作
        boolean b = verifyFenceAuthority(userId, id);
        if (b) {
            //根据id删除围栏
            Integer i = fenceInfoService.deleteH5FenceById(id);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 修改围栏
     *
     * @param fenceInfo
     * @param request
     * @return
     */
    @PutMapping("/modifyH5Fence")
    public RespEntity modifyH5Fence(@RequestBody H5Fence fenceInfo, HttpServletRequest request) {
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("modifyH5Fence : fenceInfo = {}" + fenceInfo.toString());
        //鉴权
        boolean b = verifyFenceAuthority(userId, fenceInfo.getId());
        if (b) {
            //判断围栏名称是否重复（对于一个设备而言）
            //根据设备imei查找这个设备的所有围栏
            List<H5Fence> fenceList = fenceInfoService.getH5FenceByImei(fenceInfo.getImei());
            for (H5Fence fence : fenceList) {
                if ((!fence.getId().equals(fenceInfo.getId())) && fence.getFenceName().equals(fenceInfo.getFenceName())) {
                    return new RespEntity(RespCode.DEVICE_FENCE_NAME_REPEAT);
                }
            }
            //修改围栏信息
            Integer i = fenceInfoService.modifyH5FenceById(fenceInfo);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 新增围栏
     *
     * @param fenceInfo
     * @param request
     * @return
     */
    @PostMapping("/addH5FenceInfo")
    public RespEntity addH5FenceInfo(@RequestBody H5Fence fenceInfo, HttpServletRequest request) {
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("addH5FenceInfo : fenceInfo = {}" + fenceInfo.toString());
        DeviceInfo device = deviceInfoService.getDeviceInfoByDeviceId(fenceInfo.getDeviceId());
        //鉴权
        boolean b = veryAuthentication(userId, fenceInfo.getDeviceId());
        if (b) {
            //判断围栏名称是否重复（对于一个设备而言）
            //根据学生id查找这个学生的所有围栏
            List<H5Fence> fenceList = fenceInfoService.getH5FenceByImei(device.getImei());
            for (H5Fence fence : fenceList) {
                if (fence.getFenceName().equals(fenceInfo.getFenceName())) {
                    return new RespEntity(RespCode.DEVICE_FENCE_NAME_REPEAT);
                }
            }
            //根据用户id获取客户id
            Integer cusId = h5Service.getCusIdByUserId(userId);
            //补全新增信息
            fenceInfo.setCreateTime(System.currentTimeMillis());
            fenceInfo.setCustomerId(cusId);
            fenceInfo.setImei(device.getImei());
            fenceInfo.setLastUpdateTime(System.currentTimeMillis());
            //新增围栏
            Integer i = fenceInfoService.addH5Fence(fenceInfo);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 获取一个设备的所有存在的告警类型
     *
     * @param deviceId
     * @param request
     * @return
     */
    @GetMapping("/getWarningType")
    public RespEntity getWarningType(@RequestParam("deviceId") Integer deviceId, HttpServletRequest request) {
        logger.info("getWarningType : deviceId = {}" + deviceId.toString());
        //根据学生id获取该学生的所有存在的告警类型
        List<Map<String, Object>> warnTypeList = logService.getWarningTypeByDeviceId(deviceId);
        //去重，如果有一个类型有两笔相同时间的告警类型，取id最大的那个
        List<Optional<Map<String, Object>>> collect = warnTypeList.stream().collect(Collectors.groupingBy(e -> e.get("warning_type"))).values().stream().map(e -> {
            return e.stream().max((e1, e2) -> (Integer) e1.get("id") > (Integer) e2.get("id") ? 1 : -1);
        }).collect(Collectors.toList());
        List<Map<String, Object>> result = new ArrayList<>();
        //查询告警类型消息状态
        Map<String, Object> isNewMap = redisService.getHash(Constants.WARN_TYPE_IS_NEW_H5.concat(deviceId.toString()));
        boolean flag = isNewMap == null ? true : false;
        //拼凑返回的信息
        collect.stream().forEach(e -> {
            Map<String, Object> map = e.get();
            Integer type = (Integer) map.get("warning_type");
            Long time = (Long) map.get("warning_time");
            //暂时不做关机告警记录的显示，6为关机告警记录
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            map.put("time", sdf.format(new Date((Long) map.get("warning_time"))));
            if (type == Constants.SOS_WARNING_TYPE) {
                map.put("warnName", "SOS提醒");
                map.put("content", "您的设备".concat("于").concat((String) map.get("address")).concat("拨打SOS号码"));
                if (!flag && isNewMap.get("sos") != null) {
                    Long oldTime = (Long) isNewMap.get("sos");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                result.add(map);
            } else if (type == Constants.LOW_BATTERY_WARNING_TYPE) {
                map.put("warnName", "低电量提醒");
                map.put("content", "您的设备".concat("电量不足15%，请及时充电"));
                if (!flag && isNewMap.get("lowBattery") != null) {
                    Long oldTime = (Long) isNewMap.get("lowBattery");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                result.add(map);
            } else if (type == Constants.ENTER_FENCE_WARNING_TYPE) {
                map.put("warnName", "围栏提醒");
                String fenceName = map.get("fence_name") == null ? "" : (String) map.get("fence_name");
                map.put("content", "您的设备".concat("进入").concat(fenceName).concat("围栏"));
                map.put("warning_type", 5);
                if (!flag && isNewMap.get("fence") != null) {
                    Long oldTime = (Long) isNewMap.get("fence");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                result.add(map);
            } else if (type == Constants.LEFT_WARNING_TYPE) {
                map.put("warnName", "围栏提醒");
                String fenceName = map.get("fence_name") == null ? "" : (String) map.get("fence_name");
                map.put("content", "您的设备".concat("出").concat(fenceName).concat("围栏"));
                if (!flag && isNewMap.get("fence") != null) {
                    Long oldTime = (Long) isNewMap.get("fence");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                map.put("warning_type", 5);
                result.add(map);
            } else if (type == Constants.SHUT_DOWN_WARNING_TYPE) {
                map.put("warnName", "关机提醒");
                map.put("content", "您的设备".concat("已关机"));
                if (!flag && isNewMap.get("shutdown") != null) {
                    Long oldTime = (Long) isNewMap.get("shutdown");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                result.add(map);
            } else if (type == Constants.POWER_ON_WARNING_TYPE) {
                map.put("warnName", "开机提醒");
                map.put("content", "您的设备".concat("已开机"));
                if (!flag && isNewMap.get("powerOn") != null) {
                    Long oldTime = (Long) isNewMap.get("powerOn");
                    boolean isNew = time > oldTime ? true : false;
                    map.put("isNew", isNew);
                } else {
                    map.put("isNew", true);
                }
                result.add(map);
            }
        });
        //合并出围栏和入围栏信息
        List<Optional<Map<String, Object>>> result2 = result.stream().collect(Collectors.groupingBy(e -> e.get("warning_type"))).values().stream().map(e -> {
            return e.stream().max((e1, e2) -> (Integer) e1.get("id") > (Integer) e2.get("id") ? 1 : -1);
        }).collect(Collectors.toList());
        return new RespEntity(RespCode.SUCCESS, result2);
    }

    /**
     * 根据类型和时间去更新一个类型是否是最新记录
     *
     * @param request
     * @return
     */
    @PostMapping("/setMessIsNew")
    public RespEntity setMessIsNew(@RequestBody JSONObject data,
                                   HttpServletRequest request) {
        Integer type = data.getInteger("type");
        Boolean isNew = data.getBoolean("isNew");
        Long time = data.getLong("time");
        Integer deviceId = data.getInteger("deviceId");
        logger.info("setMessIsNew : type = {},isNew = {},time = {},deviceId = {}", type.toString(), isNew.toString(), time.toString(), deviceId.toString());
        if (isNew) {
            //如果是新消息则修改存储时间
            String key = Constants.WARN_TYPE_IS_NEW_H5.concat(deviceId.toString());
            boolean b = redisService.hasKey(key);
            if (!b) {
                Map<String, Object> map = new HashMap<>();
                String name = "";
                if (type == Constants.LOW_BATTERY_WARNING_TYPE) {
                    name = "lowBattery";
                } else if (type == Constants.SOS_WARNING_TYPE) {
                    name = "sos";
                } else if (type == 5) {
                    name = "fence";
                } else if (type == Constants.POWER_ON_WARNING_TYPE) {
                    name = "powerOn";
                } else if (type == Constants.SHUT_DOWN_WARNING_TYPE) {
                    name = "shutdown";
                } else if (type == 0) {
                    name = "school";
                }
                map.put(name, time);
                redisService.setHash2(key, map, 0, TimeUnit.SECONDS);
            } else {
                Map<String, Object> map = redisService.getHash(key);
                if (type == Constants.LOW_BATTERY_WARNING_TYPE) {
                    map.put("lowBattery", time);
                } else if (type == Constants.SOS_WARNING_TYPE) {
                    map.put("sos", time);
                } else if (type == 5) {
                    map.put("fence", time);
                } else if (type == Constants.POWER_ON_WARNING_TYPE) {
                    map.put("powerOn", time);
                } else if (type == Constants.SHUT_DOWN_WARNING_TYPE) {
                    map.put("shutdown", time);
                } else if (type == 0) {
                    map.put("school", time);
                }
                redisService.setHash2(key, map, 0, TimeUnit.SECONDS);
            }
        }
        return new RespEntity(RespCode.SUCCESS);
    }


    /**
     * 获取告警记录
     *
     * @param request
     * @return
     */
    @PutMapping("/getWarningList")
    public RespEntity getWarningList(@RequestBody JSONObject data, HttpServletRequest request) {
        Integer deviceId = (Integer) data.get("deviceId");
        Integer warnType = (Integer) data.get("warnType");
        logger.info("getWarningList : data = {}" + data.toString());
        //根据学生id和类型查询告警记录
        List<Map<String, Object>> warnList = logService.getWarningListByDeviceIdAndType(deviceId, warnType);
        warnList.stream().forEach(e -> {
            Integer type = (Integer) e.get("warning_type");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            e.put("time", sdf.format(new Date((Long) e.get("warning_time"))));
            if (type == Constants.SOS_WARNING_TYPE) {
                e.put("warnName", "SOS提醒");
                e.put("content", "您的设备".concat("于").concat((String) e.get("address")).concat("拨打SOS号码"));
            } else if (type == Constants.LOW_BATTERY_WARNING_TYPE) {
                e.put("warnName", "低电量提醒");
                e.put("content", "您的设备".concat("电量不足15%，请及时充电"));
            } else if (type == Constants.ENTER_FENCE_WARNING_TYPE) {
                e.put("warnName", "围栏提醒");
                String fenceName = e.get("fence_name") == null ? "" : (String) e.get("fence_name");
                e.put("content", "您的设备".concat("进入").concat(fenceName).concat("围栏"));
                e.put("warning_type", 5);
            } else if (type == Constants.LEFT_WARNING_TYPE) {
                e.put("warnName", "围栏提醒");
                String fenceName = e.get("fence_name") == null ? "" : (String) e.get("fence_name");
                e.put("content", "您的设备".concat("出").concat(fenceName).concat("围栏"));
                e.put("warning_type", 5);
            } else if (type == Constants.SHUT_DOWN_WARNING_TYPE) {
                e.put("warnName", "关机提醒");
                e.put("content", "您的设备".concat("已关机"));
            } else if (type == Constants.POWER_ON_WARNING_TYPE) {
                e.put("warnName", "开机提醒");
                e.put("content", "您的设备".concat("已开机"));
            }
        });
        return new RespEntity(RespCode.SUCCESS, warnList);
    }

    /**
     * 立即定位
     *
     * @param deviceId
     * @param request
     * @return
     */
    @GetMapping("/getImmediatelyLocation")
    public RespEntity getImmediatelyLocation(@RequestParam("deviceId") Integer deviceId, HttpServletRequest request) {
        logger.info("getImmediatelyLocation : deviceId = {}" + deviceId.toString());
        //获取用户信息
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        List<Integer> deviceIdList = new ArrayList<>();
        if (deviceId == 0) {
            //查询所有设备
            deviceIdList = h5Service.deviceIdList(userId);
        } else {
            deviceIdList.add(deviceId);
        }
        //根据设备id列表获取imei
        List<String> imeiList = deviceInfoService.getImeiListByDeviceIdList(deviceIdList);
        if (imeiList == null || imeiList.size() == 0) {
            return new RespEntity(RespCode.DEVICE_NOT_FOUND);
        }
        if (deviceId == 0) {
            //多个下发
            Integer success = 0;
            Integer all = imeiList.size();
            Integer offLine = 0;
            Integer fail = 0;
            for (String imei : imeiList) {
                if (StringUtils.isBlank(imei)) {
                    fail++;
                    continue;
                }
                String commandNumber = getCurTime();
                boolean isOnline = deviceOnline(imei);
                if (isOnline) {
                    //设备在线则进行指令下发
                    boolean b = commandSendUtils.queryDeviceLocation(imei, commandNumber, Constants.H5_COMMAND_USER_ID, isOnline, false);
                    if (b) {
                        success++;
                        continue;
                    }
                    fail++;
                }
                offLine++;
            }
            logger.info("/immediatelyLocation:all = {} ,success= {},offLine = {},fail = {}", all.toString(), success.toString(), offLine.toString(), fail.toString());
            return new RespEntity(RespCode.SUCCESS);
        } else {
            //单个下发
            String imei = imeiList.get(0);
            if (StringUtils.isBlank(imei)) {
                return new RespEntity(RespCode.DEVICE_NOT_FOUND);
            }
            String commandNumber = getCurTime();
            boolean isOnline = deviceOnline(imei);
            if (isOnline) {
                //设备在线则进行指令下发
                boolean b = commandSendUtils.queryDeviceLocation(imei, commandNumber, Constants.H5_COMMAND_USER_ID, isOnline, false);
                if (b) {
                    return new RespEntity(RespCode.SUCCESS);
                }
                return new RespEntity(RespCode.FAILED);
            }
            return new RespEntity(RespCode.DEVICE_OFF_LINE);
        }
    }

    /**
     * 获取设置页各模式的设置状态
     */
    @GetMapping("/getModeStatus")
    public RespEntity getModeStatus(@RequestParam("deviceId") Integer deviceId) {
        logger.info("/getModeStatus : deviceId = {} ", deviceId.toString());
        //根据学生id获取设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        //获取定位模式的修改状态
        Map<String, Object> map = deviceInfoService.getModeStatusByDeviceId(deviceInfo.getDeviceId(), deviceInfo.getImei());
        /*   map.put("locateMode", deviceInfo.getWorkingPattern() == null ? Constants.DEFAULT_WORK_PATTERN : deviceInfo.getWorkingPattern());*/
        return new RespEntity(RespCode.SUCCESS, map);
    }

    /**
     * 获取定位模式的信息
     */
    @GetMapping("/getLocateModeMess")
    public RespEntity getLocateModeMess(@RequestParam("deviceId") Integer deviceId, HttpServletRequest request) {
        logger.info("/getLocateModeMess : deviceId = {} ", deviceId.toString());
        //根据学生id获取设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        //获取设备的定位模式信息
        Map<String, Object> result = new HashMap<>();
        if (deviceInfo.getWorkingPattern() == null) {
            result.put("realTimeMode", Constants.UP_INTERVAL);
            result.put("powerSaveMode", Constants.POWER_SAVING_MODEL_UP_INTERVAL);
            result.put("type", Constants.DEFAULT_WORK_PATTERN);
        } else if (deviceInfo.getWorkingPattern() == Constants.DEFAULT_WORK_PATTERN) {
            result.put("realTimeMode", deviceInfo.getUpInterval());
            result.put("powerSaveMode", Constants.POWER_SAVING_MODEL_UP_INTERVAL);
            result.put("type", Constants.DEFAULT_WORK_PATTERN);
        } else if (deviceInfo.getWorkingPattern() == Constants.POWER_SAVING_MODEL) {
            result.put("realTimeMode", Constants.UP_INTERVAL);
            result.put("powerSaveMode", deviceInfo.getUpInterval());
            result.put("type", Constants.POWER_SAVING_MODEL);
        }
       /* result.put("mode", deviceInfo.getWorkingPattern() == null ? Constants.DEFAULT_WORK_PATTERN : deviceInfo.getWorkingPattern());
        result.put("interval", deviceInfo.getUpInterval() == null ? Constants.UP_INTERVAL : deviceInfo.getUpInterval());*/
        return new RespEntity(RespCode.SUCCESS, result);
    }

    /**
     * 设置定位模式
     */
    @PostMapping("/setLocateMode")
    public RespEntity setLocateMode(@RequestBody H5LocateVO data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/setLocateMode : data = {} ", data.toString());
        boolean b = veryAuthentication(userId, data.getDeviceId());
        if (b) {
            //获取设备信息
            DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(data.getDeviceId());
            if (deviceInfo != null) {
                //判断设备是否在线
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                //获取流水号
                String command = getCurTime();
                boolean b1 = commandSendUtils.setDeviceMode(deviceInfo.getImei(), command, data.getMode(), data.getInterval(), isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
                return new RespEntity(RespCode.FAILED);
            }
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 获取睡眠模式信息
     */
    @GetMapping("/getSleepModeMess")
    public RespEntity getSleepModeMess(@RequestParam("deviceId") Integer deviceId, HttpServletRequest request) {
        logger.info("/getSleepModeMess : deviceId = {} ", deviceId.toString());
        //根据学生id获取设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        //获取设备获取设备设置信息
        DeviceSetting setting = deviceSettingService.getDeviceSettingByDeviceId(deviceInfo.getDeviceId());
        Integer sleepSwitch = setting.getSleepSwitch();
        String sleepStart = setting.getSleepStart();
        String sleepEnd = setting.getSleepEnd();
        Map<String, Object> result = new HashMap<>();
        result.put("sleepSwitch", sleepSwitch == null ? Constants.SLEEP_SWITCH_CLOSE : sleepSwitch);
        result.put("sleepStart", StringUtils.isBlank(sleepStart) ? Constants.SLEEP_DEFAULT_START : sleepStart);
        result.put("sleepEnd", StringUtils.isBlank(sleepEnd) ? Constants.SLEEP_DEFAULT_END : sleepEnd);
        return new RespEntity(RespCode.SUCCESS, result);
    }

    /**
     * 设置睡眠模式
     */
    @PostMapping("/setSleepMode")
    public RespEntity setSleepMode(@RequestBody H5SleepModeVO data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/setSleepMode : data = {} ", data.toString());
        boolean b = veryAuthentication(userId, data.getDeviceId());
        if (b) {
            //获取设备信息
            DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(data.getDeviceId());
            if (deviceInfo != null) {
                //判断设备是否在线
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                //如果是关闭，则获取数据库中的开始结束时间
                DeviceSetting setting = deviceSettingService.getDeviceSettingByDeviceId(deviceInfo.getDeviceId());
                if (setting == null) {
                    return new RespEntity(RespCode.DEVICE_SETTING_NOT_EXIST);
                }
                if (data.getSwitchFlag() == Constants.SLEEP_SWITCH_CLOSE) {
                    data.setStartTime(StringUtils.isBlank(setting.getSleepStart()) ? Constants.SLEEP_DEFAULT_START : setting.getSleepStart());
                    data.setEndTime(StringUtils.isBlank(setting.getSleepEnd()) ? Constants.SLEEP_DEFAULT_END : setting.getSleepEnd());
                }
                //获取流水号
                String command = getCurTime();
                boolean b1 = commandSendUtils.setSleepTimeAutoChangeMode(deviceInfo.getImei(), command, data.getStartTime(), data.getEndTime(), data.getSwitchFlag(), isOnline, Constants.H5_COMMAND_USER_ID, false);
                if (b1) {
                    //加个判断，如果现在正处于睡眠模式中，则提示模式结束后执行指令
                    if (setting.getSleepSwitch() != null && setting.getSleepSwitch() == Constants.SLEEP_SWITCH_OPEN) {
                        boolean b2 = judgeSleepTimeReply(setting.getSleepStart(), setting.getSleepEnd());
                        if (b2) {
                            return new RespEntity(RespCode.WAIT_END_SET_SLEEP_TIME);
                        }
                    }
                    return new RespEntity(RespCode.SUCCESS);
                }
                return new RespEntity(RespCode.FAILED);
            }
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 远程重启
     */
    @GetMapping("/restartDevice")
    public RespEntity restartDevice(@RequestParam("deviceId") Integer deviceId, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/restartDevice : deviceId = {} ", deviceId.toString());
        boolean b = veryAuthentication(userId, deviceId);
        if (b) {
            //获取设备信息
            DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
            if (deviceInfo != null) {
                //判断设备是否在线
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                if (isOnline) {
                    //获取流水号
                    String command = getCurTime();
                    boolean b1 = commandSendUtils.restartDevice(deviceInfo.getImei(), command, Constants.H5_COMMAND_USER_ID);
                    if (b1) {
                        return new RespEntity(RespCode.SUCCESS);
                    }
                    return new RespEntity(RespCode.FAILED);
                }
                return new RespEntity(RespCode.DEVICE_NOT_ONLINE);
            }
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 查看设备的静默状态
     */
    @GetMapping("/getSilentShutDownStatus")
    public RespEntity getSilentShutDownStatus(@RequestParam("deviceId") Integer deviceId, HttpServletRequest request) {
        logger.info("/getSilentShutDownStatus : deviceId = {} ", deviceId.toString());
        //根据学生id获取设备信息
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        //获取设备获取设备设置信息
        DeviceSetting setting = deviceSettingService.getDeviceSettingByDeviceId(deviceInfo.getDeviceId());
        Map<String, Object> map = new HashMap<>();
        map.put("silentStatus", setting.getSilentShutdown() == null ? Constants.SILENT_SHUTDOWN_CLOSE : setting.getSilentShutdown());
        return new RespEntity(RespCode.SUCCESS, map);
    }

    /**
     * 设置静默关机
     */
    @PostMapping("/setSilentShutdown")
    public RespEntity setSilentShutdown(@RequestBody SilentShutdownVo data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        logger.info("/setSilentShutdown : data = {} ", data.toString());
        boolean b = veryAuthentication(userId, data.getDeviceId());
        if (b) {
            //获取设备信息
            DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(data.getDeviceId());
            if (deviceInfo != null) {
                //判断设备是否在线
                boolean isOnline = deviceOnline(deviceInfo.getImei());
                //获取流水号
                String command = getCurTime();
                //进行指令下发
                boolean b1 = commandSendUtils.setShutDownSilent(data.getFlagSwitch(), deviceInfo.getImei(), command, Constants.H5_COMMAND_USER_ID, isOnline, false);
                if (b1) {
                    return new RespEntity(RespCode.SUCCESS);
                }
                return new RespEntity(RespCode.FAILED);
            }
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 查询学生的闹钟信息
     */
    @GetMapping("/getAlarmMess")
    public RespEntity getAlarmMess(@RequestParam("deviceId") Integer deviceId, HttpServletRequest request) {
        logger.info("/getAlarmMess : deviceId = {} ", deviceId.toString());
        Map<String, Object> result = new HashMap<>();
        //首先判断设备是否是有屏幕
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        result.put("if_screen", true);
        //有屏幕则查找闹钟信息
        List<Alarm> alarmList = deviceAlarmService.getAlarmListByDeviceId(deviceInfo.getDeviceId());
        //如果是一次性且开启的闹钟，还需要判断是否已经响过了，如果已经响过了则关闭（只是数据库关闭）
        alarmList.stream().forEach(e -> {
            String repeatTime = e.getRepeatTime();
            if ("0000000".equals(repeatTime) && e.getFlag() == 1) {
                Long createTime = e.getCreateTime();
                String time = e.getTime();
                boolean b = judgeIfAlarm(createTime, time);
                if (b) {
                    //已经响过了，则关闭
                    e.setFlag(0);
                    //修改数据库数据
                    deviceAlarmService.closeAlarmById(e.getId(), 0);
                }
            }
        });
        result.put("data", alarmList);
        return new RespEntity(RespCode.SUCCESS, result);
    }

    /**
     * 开启关闭闹钟
     */
    @PostMapping("/openOrCloseAlarm")
    public RespEntity openOrCloseAlarm(@RequestBody JSONObject data, HttpServletRequest request) {
        Integer deviceId = data.getInteger("deviceId");
        Integer id = data.getInteger("id");
        Integer flag = data.getInteger("flag");
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        /*Integer userId = 3;*/
        logger.info("/openOrCloseAlarm : deviceId = {} ,id={},flag={}", deviceId.toString(), id.toString(), flag.toString());
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        Alarm alarm = deviceAlarmService.queryAlarmById(id);
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        boolean b = veryAuthentication(userId, deviceId);
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            //设置闹钟开关
            int realFlag = 0;
            realFlag = flag == 0 ? 1 : 0;
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setCommandNumber(commandNumber);
            deviceAlarm.setImei(deviceInfo.getImei());
            deviceAlarm.setFlag(realFlag);
            deviceAlarm.setName(alarm.getName());
            deviceAlarm.setRepeatTime(alarm.getRepeatTime());
            deviceAlarm.setSequence(alarm.getSequence());
            deviceAlarm.setTime(alarm.getTime());
            boolean b1 = commandSendUtils.setAlarm(deviceAlarm, Constants.H5_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //修改数据库信息
                alarm.setFlag(realFlag);
                alarm.setStatus(Constants.DEVICE_ALARM_STAY_UPDATE);
                alarm.setCommandNumber(commandNumber);
                if (realFlag == 1 && "0000000".equals(alarm.getRepeatTime())) {
                    alarm.setCreateTime(System.currentTimeMillis());
                }
                int i = deviceAlarmService.modifyAlarm(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 添加闹钟
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/addAlarm")
    public RespEntity addAlarm(@RequestBody AlarmVO data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        /*Integer userId = 3;*/
        logger.info("/addAlarm :userId={},data={}", userId.toString(), data.toString());
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(data.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        boolean b = veryAuthentication(userId, data.getDeviceId());
        //获取一个可用序列号
        Integer sequence = getAlarmSequence(deviceInfo.getDeviceId());
        if (sequence == 0) {
            return new RespEntity(RespCode.ALARM_HAD_FULL);
        }
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            //设置闹钟开关
            Integer flag = 1;
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setCommandNumber(commandNumber);
            deviceAlarm.setImei(deviceInfo.getImei());
            deviceAlarm.setFlag(flag);
            deviceAlarm.setName(data.getName());
            deviceAlarm.setRepeatTime(data.getRepeat());
            deviceAlarm.setSequence(sequence);
            deviceAlarm.setTime(data.getTime());
            boolean b1 = commandSendUtils.setAlarm(deviceAlarm, Constants.H5_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //添加一个闹钟
                Alarm alarm = new Alarm();
                alarm.setCreateTime(System.currentTimeMillis());
                alarm.setCommandNumber(commandNumber);
                alarm.setStatus(Constants.DEVICE_ALARM_STAY_ADD);
                alarm.setFlag(flag);
                alarm.setRepeatTime(data.getRepeat());
                alarm.setDeviceId(deviceInfo.getDeviceId());
                alarm.setName(data.getName());
                alarm.setTime(data.getTime());
                alarm.setSequence(sequence);
                int i = deviceAlarmService.addAlarm(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 修改闹钟
     *
     * @param data
     * @param request
     * @return
     */
    @PostMapping("/modifyAlarm")
    public RespEntity modifyAlarm(@RequestBody AlarmVO data, HttpServletRequest request) {
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        /*Integer userId = 3;*/
        logger.info("/modifyAlarm :userId={},data={}", userId.toString(), data.toString());
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(data.getDeviceId());
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        boolean b = veryAuthentication(userId, data.getDeviceId());
        //获取闹钟信息
        Alarm alarm = deviceAlarmService.queryAlarmById(data.getId());
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            deviceAlarm.setCommandNumber(commandNumber);
            deviceAlarm.setImei(deviceInfo.getImei());
            deviceAlarm.setFlag(alarm.getFlag());
            deviceAlarm.setName(data.getName());
            deviceAlarm.setRepeatTime(data.getRepeat());
            deviceAlarm.setSequence(alarm.getSequence());
            deviceAlarm.setTime(data.getTime());
            boolean b1 = commandSendUtils.setAlarm(deviceAlarm, Constants.H5_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //修改一个闹钟
                alarm.setTime(data.getTime());
                alarm.setName(data.getName());
                alarm.setStatus(Constants.DEVICE_ALARM_STAY_UPDATE);
                alarm.setCreateTime(System.currentTimeMillis());
                alarm.setCommandNumber(commandNumber);
                alarm.setRepeatTime(data.getRepeat());
                int i = deviceAlarmService.modifyAlarmMess(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 删除一个闹钟
     *
     * @param dataVo
     * @param request
     * @return
     */
    @PostMapping("/deleteAlarm")
    public RespEntity deleteAlarm(@RequestBody JSONObject dataVo, HttpServletRequest request) {
        Integer deviceId = dataVo.getInteger("deviceId");
        Integer id = dataVo.getInteger("id");
        //获取用户id
        Integer userId = getUserId(request);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        /* Integer userId = 3;*/
        logger.info("/deleteAlarm :deviceId={},id={}", deviceId.toString(), id.toString());
        DeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByDeviceId(deviceId);
        if (deviceInfo == null) {
            return new RespEntity(RespCode.DEVICE_NOT_EXIST);
        }
        boolean b = veryAuthentication(userId, deviceId);
        //获取闹钟信息
        Alarm alarm = deviceAlarmService.queryAlarmById(id);
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        if (b) {
            boolean isOnline = deviceOnline(deviceInfo.getImei());
            String commandNumber = getCurTime();
            JSONObject data = new JSONObject();
            data.put("imei", deviceInfo.getImei());
            data.put("commandNumber", commandNumber);
            data.put("sequence", alarm.getSequence());
            boolean b1 = commandSendUtils.deleteAlarm(data, Constants.H5_COMMAND_USER_ID, isOnline, false);
            if (b1) {
                //修改闹钟的状态为待删除
                alarm.setStatus(Constants.DEVICE_ALARM_DELETE);
                alarm.setCommandNumber(commandNumber);
                int i = deviceAlarmService.modifyAlarmMess(alarm);
                return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
            }
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 根据id获取一个闹钟的信息
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/getAlarmById")
    public RespEntity getAlarmById(@RequestParam("id") Integer id, HttpServletRequest request) {
        logger.info("/getAlarmById :id={}", id.toString());
        Alarm alarm = deviceAlarmService.queryAlarmById(id);
        if (alarm == null) {
            return new RespEntity(RespCode.PARAMS_ERROR);
        }
        return new RespEntity(RespCode.SUCCESS, alarm);
    }


    /**
     * 判断一次性闹钟是否已经响过了
     *
     * @param createTime
     * @param time
     * @return
     */
    public static boolean judgeIfAlarm(Long createTime, String time) {
        //根据创建时间和设置时间，算出第一次响铃时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(createTime);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        String minuteStr = minute < 10 ? "0".concat(String.valueOf(minute)) : String.valueOf(minute);
        String oldTime = String.valueOf(hour).concat(":").concat(minuteStr);
        String[] split = time.split(":");
        calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
        calendar.set(Calendar.MINUTE, Integer.valueOf(split[1]));
        Long firstAlarm = 0l;
        if (time.compareTo(oldTime) >= 0) {
            //说明第一次铃响跟创建闹钟是在同一天
            firstAlarm = calendar.getTimeInMillis();
        } else {
            //说明第一次响铃是创建闹钟的后一天
            createTime = createTime + 24 * 60 * 60 * 1000;
            Calendar calendar2 = Calendar.getInstance();
            calendar2.setTimeInMillis(createTime);
            calendar2.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
            calendar2.set(Calendar.MINUTE, Integer.valueOf(split[1]));
            firstAlarm = calendar2.getTimeInMillis();
        }
        return System.currentTimeMillis() > firstAlarm ? true : false;
    }


    /**
     * 获取一个闹钟的可用的序列号
     *
     * @param deviceId
     * @return
     */
    public Integer getAlarmSequence(Integer deviceId) {
        //获取该设备已经存在的课堂模式
        List<Alarm> list = deviceAlarmService.getAlarmListByDeviceId(deviceId);
        List<Integer> seqList = new ArrayList<>();
        for (Alarm alarm : list) {
            seqList.add(alarm.getSequence());
        }
        for (int i = 1; i <= 10; i++) {
            if (!seqList.contains(i)) {
                return i;
            }
        }
        return 0;
    }


    /**
     * 校验用户是否可以操作此围栏
     *
     * @param userId
     * @param fenceId
     * @return
     */
    public boolean verifyFenceAuthority(Integer userId, Integer fenceId) {
        //根据用户id和围栏id查询围栏
        H5Fence h5Fence = fenceInfoService.getH5FenceByCusIdAndId(userId, fenceId);
        if (h5Fence == null) {
            return false;
        }
        return true;
    }


    /**
     * 获取一个可用的SOS列表的序列号
     */
    public Integer getSosSequence(Integer deviceId) {
        //获取该设备已经存在的SOS告警记录
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceId);
        List<Integer> seqList = new ArrayList<>();
        for (DeviceSOSList deviceSOSList : sosList) {
            seqList.add(deviceSOSList.getSequence());
        }
        for (int i = 1; i <= 3; i++) {
            if (!seqList.contains(i)) {
                return i;
            }
        }
        return 0;
    }

    /**
     * 判断该用户是否可以操作该设备
     *
     * @param deviceId
     * @param userId
     * @return
     */
    public boolean veryAuthentication(Integer userId, Integer deviceId) {
        //根据用户id查询所拥有的设备
        List<Map<String, Object>> list = h5Service.deviceList(userId);
        //判断是否有权操作
        if (list != null && list.size() != 0) {
            for (Map<String, Object> map : list) {
               /* if (deviceId.intValue() == ((Integer) map.get("device_id")).intValue()) {
                    return true;
                }*/
                if (deviceId.equals((Integer) map.get("device_id"))) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取当前时间的时分秒（HHmmss）
     *
     * @return
     */
    public String getCurTime() {
        Date d = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("HH:mm:ss");
        String format = sbf.format(d);
        String[] split = format.split(":");
        String time = split[0].concat(split[1]).concat(split[2]);
        return time;
    }

    /**
     * 判断设备是否在线
     *
     * @param imei 设备imei号
     * @return 设备是否在线
     */
    public boolean deviceOnline(String imei) {
        boolean isOnline = redisService.hasKey(Constants.DEVICE_ONLINE_PREFIX + imei);
        logger.info("设备:【{}】: {}", imei, isOnline ? "在线" : "离线");
        return isOnline;
    }

    /**
     * 获取一个可用的亲情号码的序列号
     */
    public Integer getSequence(List<DeviceWhiteList> list) {
        //获取该设备已经存在的亲情号序号
        List<Integer> seqList = new ArrayList<>();
        for (DeviceWhiteList deviceWhiteList : list) {
            seqList.add(deviceWhiteList.getSequence());
        }
        for (int i = 4; i <= 6; i++) {
            if (!seqList.contains(i)) {
                return i;
            }
        }
        return 0;
    }

    /**
     * 获取一个可用的通讯录的序列号
     */
    public Integer getSequenceInLink(List<DeviceWhiteList> list) {
        //获取该设备已经存在的亲情号序号
        List<Integer> seqList = new ArrayList<>();
        for (DeviceWhiteList deviceWhiteList : list) {
            seqList.add(deviceWhiteList.getSequence());
        }
        for (int i = 7; i <= 23; i++) {
            if (!seqList.contains(i)) {
                return i;
            }
        }
        return 0;
    }

    /**
     * 获取一个课堂模式可用的序列号
     *
     * @param deviceId
     * @return
     */
    public Integer getClassSequence(Integer deviceId) {
        //获取该设备已经存在的课堂模式
        List<DeviceClassPattern> list = deviceClassPatternService.getDeviceClassesPatternByDeviceId(deviceId);
        List<Integer> seqList = new ArrayList<>();
        for (DeviceClassPattern classPattern : list) {
            seqList.add(classPattern.getSequence());
        }
        for (int i = 1; i <= 10; i++) {
            if (!seqList.contains(i)) {
                return i;
            }
        }
        return 0;
    }

    /**
     * 获取用户id
     *
     * @param request
     * @return
     */
    public Integer getUserId(HttpServletRequest request) {
        if (request.getHeader("Access-Token").equals("aaabbb")) {
            return 1;
        }
        String token = request.getHeader("Access-Token");
        String value = redisService.getValue(token);
        if (StringUtils.isBlank(value) || !value.contains(Constants.H5_TOKEN_PREFIX)) {
            return 0;
        }
        Integer h5UserId = Integer.parseInt(value.split("_")[1]);
        return h5UserId;
    }

    /**
     * 获取修改下发设置SOS的参数
     */
    public List<DeviceSOSList> getModifySetSOSList(DeviceSOSList list, Integer deviceId) {
/*        //根据设备id查找SOS号码记录
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceId);
        List<Integer> sequenceList = sosList.stream()
                .map(DeviceSOSList::getSequence)
                .collect(Collectors.toList());
        Iterator<DeviceSOSList> iterator = sosList.iterator();
        while(iterator.hasNext()){
            //将从数据库中查询出来的对应的要修改的老数据从list中删除
            DeviceSOSList next = iterator.next();
            if(next.getSequence() == list.getSequence()){
                iterator.remove();
            }
        }*/
        //根据设备id查找SOS号码记录
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceId);
        Iterator<DeviceSOSList> iterator = sosList.iterator();
        while (iterator.hasNext()) {
            //将从数据库中查询出来的对应的要修改的老数据从list中删除
            DeviceSOSList next = iterator.next();
            if (next.getSequence() == list.getSequence()) {
                iterator.remove();
                continue;
            }
            //如果是碰到状态为待删除的，也将它移除
            if (next.getStatus().equals(Constants.DEVICE_WHITE_DELETE)) {
                iterator.remove();
            }
        }
        //修改界限
        List<Integer> sequenceList = sosList.stream()
                .map(DeviceSOSList::getSequence)
                .collect(Collectors.toList());
        for (int i = 1; i <= 3; i++) {
            //如果是修改的那笔数据的sequence，则直接把修改后的新数据加入进去
            if (i == list.getSequence()) {
                sosList.add(list);
                continue;
            }
            if (sequenceList.contains(i)) {
                continue;
            }
            DeviceSOSList deviceSOSList = new DeviceSOSList();
            deviceSOSList.setSequence(i);
            deviceSOSList.setSosName("");
            deviceSOSList.setSosPhone("");
            sosList.add(deviceSOSList);
        }
        sosList = sosList.stream()
                .sorted(Comparator.comparing(DeviceSOSList::getSequence))
                .collect(Collectors.toList());
        logger.info("---更新SOS" + sosList.toString());
        return sosList;
    }

    /**
     * 获取添加下发指令设置SOS的参数
     */
    public List<DeviceSOSList> getAddSetSOSList(DeviceSOSList list, Integer deviceId) {
        //根据设备id查找SOS号码记录，这里的sos记录会影响到下面的结果，因为如果是有2和3，则顺序就位231了
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceId);
        //修改内容
        Iterator<DeviceSOSList> iterator = sosList.iterator();
        while (iterator.hasNext()) {
            DeviceSOSList next = iterator.next();
            //如果数据库有待删除的数据，那么下发的时候需要下发空值，所以这里需要删除掉
            if (next.getStatus().equals(Constants.DEVICE_WHITE_DELETE)) {
                iterator.remove();
            }
        }
        //修改界限
        // 获取数据库有的id
        List<Integer> sequenceList = sosList.stream().map(DeviceSOSList::getSequence).collect(Collectors.toList());
        for (Integer i = 1; i <= 3; i++) {
            // 如果有，则不管，否则就加一个空的
            if (sequenceList.contains(i)) {
                continue;
            }
            DeviceSOSList deviceSOSList = new DeviceSOSList();
            deviceSOSList.setSequence(i);
            deviceSOSList.setSosName("");
            deviceSOSList.setSosPhone("");
            sosList.add(deviceSOSList);
        }
        // 排序
        sosList = sosList.stream().sorted(Comparator.comparing(DeviceSOSList::getSequence)).collect(Collectors.toList());
        logger.info("---新增SOS" + sosList.toString());
        return sosList;
    }

    /**
     * 获取删除下发指令设置SOS的参数
     */
    public List<DeviceSOSList> getDelSetSOSList(DeviceSOSList list, Integer deviceId) {
        //根据设备id查找SOS号码记录
        List<DeviceSOSList> sosList = logService.getSOSListByDeviceId(deviceId);
        // 排除掉需要删除的，删除的用空
        Iterator iterator = sosList.iterator();
        while (iterator.hasNext()) {
            DeviceSOSList sos = (DeviceSOSList) iterator.next();
            if (sos.getSequence().equals(list.getSequence())) {
                iterator.remove();
                continue;
            }
            //如果是碰到状态为待删除的，也将它移除
            if (sos.getStatus().equals(Constants.DEVICE_WHITE_DELETE)) {
                iterator.remove();
            }
        }
        List<Integer> sequenceList = sosList.stream().map(DeviceSOSList::getSequence).collect(Collectors.toList());
        for (int i = 1; i <= 3; i++) {
            if (sequenceList.contains(i)) {
                continue;
            }
            DeviceSOSList deviceSOSList = new DeviceSOSList();
            deviceSOSList.setSequence(i);
            deviceSOSList.setSosName("");
            deviceSOSList.setSosPhone("");
            sosList.add(deviceSOSList);
        }
        sosList = sosList.stream()
                .sorted(Comparator.comparing(DeviceSOSList::getSequence))
                .collect(Collectors.toList());
        logger.info("---删除SOS" + sosList.toString());
        return sosList;
    }

    /**
     * 筛选轨迹数据，未超过十米就筛掉
     *
     * @param list
     * @return
     */
    public List<Map<String, Object>> dealLocation(List<Map<String, Object>> list) {
        if (list == null || list.size() <= 2) {
            return list;
        }
        List<Map<String, Object>> result = new ArrayList<>();
        Map<String, Object> curr = list.get(0);
        result.add(curr);
        for (int i = 1; i < list.size() - 1; i++) {
            String longitude = (String) curr.get("longitude");
            String latitude = (String) curr.get("latitude");
            double[] doubles = GPSUtils.gps84_To_Gcj02(Double.parseDouble(latitude), Double.parseDouble(longitude));
            String longitude2 = (String) list.get(i).get("longitude");
            String latitude2 = (String) list.get(i).get("latitude");
            double[] doubles2 = GPSUtils.gps84_To_Gcj02(Double.parseDouble(latitude2), Double.parseDouble(longitude2));
            double distance = GPSUtils.getDistance(doubles[1], doubles[0], doubles2[1], doubles2[0]);
            if (distance > 5) {
                result.add(list.get(i));
                curr = list.get(i);
            }
        }
        result.add(list.get(list.size() - 1));
        return result;
    }


    public boolean judgeSleepTimeReply(String start, String end) {
        //获取当前时间
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        String now = sdf.format(new Date(System.currentTimeMillis()));
        if (end.compareTo(start) > 0) {
            //结束时间比开始时间大
            if (now.compareTo(start) > 0 && end.compareTo(now) > 0) {
                return true;
            }
            return false;
        } else {
            //结束时间比开始时间小(跨天)
            if (now.compareTo(start) > 0 && now.compareTo(end) > 0) {
                return true;
            } else if (now.compareTo(start) < 0 && now.compareTo(end) < 0) {
                return true;
            }
            return false;
        }
    }

    @GetMapping("/testaa")
    public RespEntity testaa(HttpServletRequest request) {
        //创建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        //访问的接口地址
        String url = "http://localhost:7503/getaa";
        HttpGet httpGet = new HttpGet(url);
        try {
            CloseableHttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                //请求方法成功
                HttpEntity entity = response.getEntity();
                entity.getContent();
                String s = EntityUtils.toString(entity, "UTF-8");
                System.out.println(s);
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}
